﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using MineSweeper.ValidationRules;
using System.ComponentModel.DataAnnotations;
using SwiftMVVM.ViewModel;
using System.Windows.Interop;
using System.Windows.Media;

namespace MineSweeper.Data
{
    /// <summary>
    /// This class will wrap the options selectable
    /// by the user. It will also contain the majority 
    /// or the validation logic
    /// </summary>
    public abstract class GameOptions : BindingObject, IDataErrorInfo
    {
        /// <summary>
        /// Initializes the options
        /// </summary>
        public GameOptions()
        {
            this.Difficulty = (GameDifficulty)Properties.Settings.Default.GameOptionDifficultyInt;
            this.CustomHeight = Properties.Settings.Default.GameOptionHeight;
            this.CustomWidth = Properties.Settings.Default.GameOptionWidth;
            this.CustomMineCount = Properties.Settings.Default.GameOptionMines;
            this.AllowCheckMarks = Properties.Settings.Default.GameOptionAllowCheckmarks;
            //SL 7/18/13 I added this because I noticed that the the value given to the function I created in the settings menu was not being used.
            this.UseSoftwareRendering = Properties.Settings.Default.UseSoftwareRendering;
            this.RandomGameStyleAndBoard = Properties.Settings.Default.ChooseGameStyleAndBoardRandom;
            this.ActiveThemeName = Properties.Settings.Default.ActiveThemeName;
            this.ActiveIconName = Properties.Settings.Default.ActiveIconName;
        }

        /// <summary>
        /// Saves the changes to the option settings
        /// </summary>
        public void Save()
        {
            Properties.Settings.Default.GameOptionDifficultyInt = (int)this.Difficulty;
            Properties.Settings.Default.GameOptionHeight = this.CustomHeight;
            Properties.Settings.Default.GameOptionWidth = this.CustomWidth;
            Properties.Settings.Default.GameOptionMines = this.CustomMineCount;
            Properties.Settings.Default.GameOptionAllowCheckmarks = this.AllowCheckMarks;
            //SL 7/18/13 I added this line because, while testing, I realized that the value of UseSoftwareRendering was not saved when the "OK" button was selected.
            Properties.Settings.Default.UseSoftwareRendering = this.UseSoftwareRendering;
            Properties.Settings.Default.ChooseGameStyleAndBoardRandom = this.RandomGameStyleAndBoard;
            Properties.Settings.Default.ActiveThemeName = this.ActiveThemeName;
            Properties.Settings.Default.ActiveIconName = this.ActiveIconName;
            Properties.Settings.Default.RaiseSettingsModified();
            RenderOptions.ProcessRenderMode = UseSoftwareRendering ? RenderMode.SoftwareOnly : RenderMode.Default;

        }

        /// <summary>
        /// Saves the changes to the option settings
        /// </summary>
        public void SaveAppearance()
        {
            if (this.RandomGameStyleAndBoard)
            {
                Random rand = new Random();
                int tiles = rand.Next(0, 2);
                int icon = rand.Next(0, 2);
                string randomTiles, randomIcon;
                if (tiles == 0) {
                    randomTiles = "BlueTilesMinesweeper";
                } else {
                    randomTiles = "GreenTilesMinesweeper";
                }
                if (icon == 0) {
                    randomIcon = "mineSweeper";
                }
                else {
                    randomIcon = "flowerGarden";
                }

                Properties.Settings.Default.ChooseGameStyleAndBoardRandom = this.RandomGameStyleAndBoard;
                Properties.Settings.Default.ActiveThemeName = randomTiles;
                Properties.Settings.Default.ActiveIconName = randomIcon;

            } else {
                Properties.Settings.Default.ChooseGameStyleAndBoardRandom = this.RandomGameStyleAndBoard;
                Properties.Settings.Default.ActiveThemeName = this.ActiveThemeName;
                Properties.Settings.Default.ActiveIconName = this.ActiveIconName;
            }
        }

        /// <summary>
        /// Determines if we're allowing checkmarks
        /// </summary>
        [NotificationProperty]
        public virtual string ActiveIconName { get; set; }

        /// <summary>
        /// Determines if we're allowing checkmarks
        /// </summary>
        [NotificationProperty]
        public virtual string ActiveThemeName { get; set; }

        /// <summary>
        /// Determines if we're allowing checkmarks
        /// </summary>
        [NotificationProperty]
        public virtual bool AllowCheckMarks { get; set; }

        /// <summary>
        /// SL 7/18/13 Determines if we're using Software Rendering
        /// </summary>
        [NotificationProperty]
        public virtual bool UseSoftwareRendering { get; set; }

        /// <summary>
        /// The difficulty of the current game
        /// </summary>
        [NotificationProperty]
        public virtual GameDifficulty Difficulty { get; set; }

        /// <summary>
        /// Determines the style of the board
        /// </summary>
        [NotificationProperty]
        public virtual bool RandomGameStyleAndBoard { get; set; }

        /// <summary>
        /// Custom game height
        /// </summary>
        [Required]
        [Range(9, 24)]
        [NotificationProperty]
        public virtual int CustomHeight { get; set; }

        /// <summary>
        /// Custom game width
        /// </summary>
        [Required]
        [Range(9, 30)]
        [NotificationProperty]
        public virtual int CustomWidth { get; set; }


        /// <summary>
        /// Custom mine count
        /// </summary>
        [Required]
        [Range(10, 668)]
        [NotificationProperty]
        public virtual int CustomMineCount { get; set; }

        /// <summary>
        /// Instantiates a new instance of GameOptions
        /// </summary>
        /// <returns>An instance of GameOptions wrapped in a notify proxy</returns>
        public static GameOptions Create()
        {
            return NotifyProxyTypeManager.Allocate<GameOptions>();
        }

        /// <summary>
        /// Gets an error message indicating what is wrong with this object. 
        /// </summary>
        string IDataErrorInfo.Error { get { return DataErrorInfoSupport.GetError(this); } }

        /// <summary>
        /// Gets the error message for the property with the given name. 
        /// </summary>
        /// <param name="memberName">The name of the property whose error message to get. </param>
        /// <returns>The error message for the property. The default is an empty string ("").</returns>
        string IDataErrorInfo.this[string memberName] { get { return DataErrorInfoSupport.GetError(this, memberName); } }
    }
}
